import { defineStore } from 'pinia';
import { setToken as persistToken, getToken as readToken, clearToken } from '@/utils/auth';
import { login as apiLogin, logout as apiLogout, me, myPerms, myMenuTree } from '@/api/auth';
import type { SysUser } from '@/types/api';

interface State {
  token: string | null;
  user: SysUser | null;
  apiPerms: string[];
  webPerms: string[];
  menus: any[];
  initialized: boolean;
}

export const useAuthStore = defineStore('auth', {
  state: (): State => ({
    token: readToken(),
    user: null,
    apiPerms: [],
    webPerms: [],
    menus: [],
    initialized: false,
  }),
  getters: {
    isLoggedIn: (s) => !!s.token,
    hasPerm: (s) => (perm: string) => s.apiPerms.includes(perm) || s.webPerms.includes(perm),
    hasAnyPerm: (s) => (perms: string[]) => perms.some(p => s.apiPerms.includes(p) || s.webPerms.includes(p)),
    hasAllPerm: (s) => (perms: string[]) => perms.every(p => s.apiPerms.includes(p) || s.webPerms.includes(p)),
  },
  actions: {
    setToken(token: string) {
      this.token = token;
      persistToken(token);
    },
    async login(payload: { username: string; password: string; captcha?: string }) {
      const res = await apiLogin(payload);
      const token = (res as any)?.data?.tokenValue || (res as any)?.tokenValue || (res as any)?.data?.token || (res as any)?.token;
      if (!token) throw new Error('登录响应未返回 token');
      this.setToken(token);
      await this.bootstrap();
    },
    async logout() {
      try { await apiLogout(); } catch {}
      this.token = null;
      this.user = null;
      this.apiPerms = [];
      this.webPerms = [];
      this.menus = [];
      this.initialized = false;
      clearToken();
    },
    async fetchMe() {
      const res = await me();
      this.user = (res as any)?.data || null;
    },
    async fetchPerms() {
      const res = await myPerms();
      const data = (res as any)?.data || { apiPerms: [], webPerms: [] };
      this.apiPerms = data.apiPerms || [];
      this.webPerms = data.webPerms || [];
    },
    async fetchMenus() {
      const res = await myMenuTree();
      this.menus = (res as any)?.data || [];
    },
    async bootstrap() {
      await Promise.all([this.fetchMe(), this.fetchPerms(), this.fetchMenus()]);
      this.initialized = true;
    },
  },
});